//
// Created by zzc on 18-2-5.
//

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmockery.h>
#include "../src/dict.h"
#include "../src/zmalloc.h"


dictType *intDictType;

// 计算哈希值的函数
unsigned int ihashFunction(const void *key)
{
    return (*(unsigned int *)key) % 10;
}

// 复制键的函数
void *ikeyDup(void *privdata, const void *key)
{
    unsigned  int *k = zmalloc(sizeof(unsigned int));
    *k = *(unsigned int *)key;
    return k;
}

// 复制值的函数
void *ivalDup(void *privdata, const void *obj)
{
    unsigned  int *k = zmalloc(sizeof(unsigned int));
    *k = *(unsigned int *)obj;
    return k;
}

// 对比键的函数
int ikeyCompare(void *privdata, const void *key1, const void *key2)
{
    return *(unsigned int *) key1 == *(unsigned int *) key2;
}

// 销毁键的函数
void ikeyDestructor(void *privdata, void *key)
{
    zfree(key);
}

// 销毁值的函数
void ivalDestructor(void *privdata, void *obj)
{
    zfree(obj);
}


void test_create(void **state)
{
    dict *d = dictCreate(intDictType, NULL);
    unsigned int i = 1;
    unsigned int v = 2;
    dictAdd(d, &i, &v);

    unsigned int *pv = dictFetchValue(d, &i);
    assert_true(*pv == v);
    dictRelease(d);
}

void test_multi(void **state) {
    dict *d = dictCreate(intDictType, NULL);
    unsigned int i = 1;
    unsigned int v;
    for (; i < 1000; i++) {
        v = i + 1;
        dictAdd(d, &i, &v);
    }

    i = 1;
    unsigned int *pv = dictFetchValue(d, &i);
    assert_true(*pv == 2);
    i++;
    pv = dictFetchValue(d, &i);
    assert_true(*pv == i+1);

    i = 100;
    pv = dictFetchValue(d, &i);
    assert_true(*pv == i+1);
    dictRelease(d);
}

void test_del(void **state) {
    dict *d = dictCreate(intDictType, NULL);
    unsigned int i = 1;
    unsigned int v;
    for (; i < 1000; i++) {
        v = i + 1;
        dictAdd(d, &i, &v);
    }

    i = 1;
    int r = dictDelete(d, &i);
    assert_true(r = DICT_OK);
    assert_true(NULL == dictFind(d, &i));
}

void test_iter(void **state) {

}

int main(int argc, char *argv[])
{
    intDictType = zmalloc(sizeof(*intDictType));
    intDictType->hashFunction = ihashFunction;
    intDictType->keyCompare = ikeyCompare;
    intDictType->keyDup = ikeyDup;
    intDictType->keyDestructor = ikeyDestructor;
    intDictType->keyDestructor = ikeyDestructor;
    intDictType->valDestructor = ivalDestructor;
    intDictType->valDup = ivalDup;
    const UnitTest tests[] = {
            unit_test(test_create),
            unit_test(test_multi),
            unit_test(test_del)


    };
    return run_tests(tests);
}
